#pragma once
#include <math.h>
//
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh437833(v=vs.85).aspx
// #include <DirectXMath.h>
//

namespace dxroids
{
   //
   // Physics for Game Developers
   //
   class Vector
   {

   public:

      static const float MinTolerance;

      Vector() : x_(0.0f), y_(0.0f) { }       
      Vector(float _x, float _y) : x_(_x), y_(_y) { } 
      Vector(Vector const & _other) : x_(_other.x_), y_(_other.y_) { } 

      float GetX() const;
      float GetY() const;      

      void SetX(float _x);
      void SetY(float _y);

      Vector & Rotate(float _rad);
      Vector & Translate(float _x, float _y);

      bool IsOrNearZeroX() const;
      bool IsOrNearZeroY() const;

      float Magnitude() const;
      float MagnitudeSquared() const;
      float DistanceSquared(Vector const & _rhs) const;

      void Normalize();

      Vector& operator += (Vector const & _rhs);
      Vector& operator -= (Vector const & _rhs);
      Vector& operator *= (float _s);
      Vector& operator /= (float _s);

   private:

      float x_;
      float y_;

   };
}

inline float dxroids::Vector::GetX() const
{
   return x_;
}

inline float dxroids::Vector::GetY() const
{
   return y_;
}

inline void dxroids::Vector::SetX(float _x)
{
   x_ = _x;
}

inline void dxroids::Vector::SetY(float _y)
{
   y_ = _y;
}

inline bool dxroids::Vector::IsOrNearZeroX() const
{
   float const x = fabs(x_);
   return x == 0.0f || x < Vector::MinTolerance;   
}

inline bool dxroids::Vector::IsOrNearZeroY() const
{
   float const y = fabs(y_);
   return y == 0.0f || y < Vector::MinTolerance;
}

inline float dxroids::Vector::Magnitude() const
{
   return sqrt( (x_ * x_) + (y_ * y_) );
}

inline float dxroids::Vector::MagnitudeSquared() const
{
   return ( (x_ * x_) + (y_ * y_) );
}

inline dxroids::Vector& dxroids::Vector::operator += (dxroids::Vector const & _rhs)
{
   return Translate(_rhs.x_, _rhs.y_);
}

inline dxroids::Vector & dxroids::Vector::Translate(float _x, float _y)
{
   x_ += _x;
   y_ += _y;
   return *this;
}

inline dxroids::Vector& dxroids::Vector::operator -= (dxroids::Vector const & _rhs)
{
   x_ -= _rhs.x_;
   y_ -= _rhs.y_;
   return *this;
}

inline dxroids::Vector& dxroids::Vector::operator *= (float _s)
{
   x_ *= _s;
   y_ *= _s;
   return *this;
}
      
inline dxroids::Vector& dxroids::Vector::operator /= (float _s)
{
   x_ /= _s;
   y_ /= _s;
   return *this;
}

inline dxroids::Vector & dxroids::Vector::Rotate(float _rad)
{   
   float const x = (x_ * ::cosf(_rad)) - (y_ * ::sinf(_rad));
   float const y = (x_ * ::sinf(_rad)) + (y_ * ::cosf(_rad));

   x_ = x;
   y_ = y;

   return *this;
}

inline float dxroids::Vector::DistanceSquared(Vector const & _rhs) const
{   
   return ((_rhs.x_ - x_) * (_rhs.x_ - x_)) + ((_rhs.y_ - y_) * (_rhs.y_ - y_));
}